package com.ddm.service.impl.webImpl;

import cn.hutool.db.PageResult;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ddm.entity.vxEntity.User;
import com.ddm.entity.webEntity.Plan;
import com.ddm.entity.webEntity.UserSubscribe;
import com.ddm.mapper.PlanMapper;
import com.ddm.mapper.UserMapper;
import com.ddm.mapper.UserSubscribeMapper;
import com.ddm.service.webService.UserSubscribeService;
import com.ddm.vo.webVo.SubscribeDetailVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.*;

/**
 * 用户订阅服务实现
 */
@Slf4j
@Service
public class UserSubscribeServiceImpl extends ServiceImpl<UserSubscribeMapper, UserSubscribe> implements UserSubscribeService {

    @Resource
    private UserSubscribeMapper userSubscribeMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private PlanMapper planMapper;


    /**
     * 查询用户的订阅详情（关联套餐表）
     */
    @Override
    public List<SubscribeDetailVO> getUserSubscribeDetail(Long userId) {
        return userSubscribeMapper.selectUserSubscribeDetail(userId);
    }

    /**
     * 查询即将到期的订阅
     */
    @Override
    public List<SubscribeDetailVO> getExpiringSubscribes(Integer days) {
        return userSubscribeMapper.selectExpiringSubscribes(days);
    }

    /**
     * 检查用户是否有有效订阅（当前日期在订阅期内）
     */
    @Override
    public Map hasValidSubscribe(Long userId) {
        QueryWrapper<UserSubscribe> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId)
                .le("start_date", LocalDate.now()) // 开始日期 <= 当前日期
                .ge("end_date", LocalDate.now()); // 结束日期 >= 当前日期
        UserSubscribe userSubscribe = getOne(queryWrapper);
        // 封装结果：有记录则返回true+subId，无记录则返回false+null
        Map<String, Object> data=new HashMap<>();
        if (userSubscribe != null) {

            data.put("state", count(queryWrapper) > 0);
            data.put("planId",userSubscribe.getPlanId());
        }
        else{
            data.put("state", false);
            data.put("planId",null);
        }
        return data;
    }

    @Override
    public boolean addSubscribe(Long userId, Long planId) {
        log.info("接收参数：userId={}, planId={}", userId, planId);
        LocalDate now = LocalDate.now();

        // 1. 校验用户是否存在
        User user = userMapper.selectById(userId);
        if (user == null || user.getDeleted() == 1) { // 软删除判断（无则删除）
            throw new IllegalArgumentException("用户不存在或已删除");
        }

        // 2. 校验套餐是否存在 + 获取套餐有效期天数
        Plan plan = planMapper.selectById(planId);
        if (plan == null) { // 软删除判断（无则删除）
            throw new IllegalArgumentException("套餐不存在或已删除");
        }
        // 从套餐表获取有效期天数（如 plan 实体有 durationDays 字段，代表“天”）
        Integer durationDays = plan.getDurationDays();
        if (durationDays == null || durationDays <= 0) {
            throw new IllegalArgumentException("套餐有效期不合法（需大于0天）");
        }
       // 3. 校验：同一用户是否已订阅同一未过期套餐（防重复）
        QueryWrapper<UserSubscribe> existWrapper = new QueryWrapper<>();
        existWrapper.eq("user_id", userId)
                .eq("plan_id", planId)
                .ge("end_date", now);
        if (userSubscribeMapper.selectCount(existWrapper) > 0) {
            throw new IllegalArgumentException("用户已订阅该未过期套餐，无需重复添加");
        }

        // 4. 构造现有 UserSubscribe 实体（自动补全所有字段）
        UserSubscribe userSubscribe = new UserSubscribe();
        userSubscribe.setUserId(userId); // 前端传递的用户ID
        userSubscribe.setPlanId(planId); // 前端传递的套餐ID
        userSubscribe.setStartDate(now); // 自动设为当前日期（立即生效）
        // 自动计算过期日期：当前日期 + 套餐有效期天数
        userSubscribe.setEndDate(now.plus(durationDays, ChronoUnit.DAYS));
        userSubscribe.setAutoRenew(0); // 默认不自动续费（可改为1）
        userSubscribe.setStatus(1); // 自动设为当前日期（立即生效）
        // 5. 插入数据库（复用现有Mapper）
        // 1. 执行插入
        userSubscribeMapper.insert(userSubscribe);
        Long newSubscribeId = userSubscribe.getId(); // 若主键是自增，插入后会自动回填 ID

        // 2. 二次查询：确认新记录是否存在（兜底）
        UserSubscribe insertedSubscribe = userSubscribeMapper.selectById(newSubscribeId);
        boolean success = insertedSubscribe != null;
        log.info("添加订阅结果，userId: {}, planId: {}, 成功: {}", userId, planId, success);
        return success;
    }

    @Override
    public boolean updateSubscribeStatus(Long subId, Integer status, Integer autoRenew) {
        log.info("传入参数:{}",autoRenew,status,subId);
        // 1. 检查订阅记录是否存在
        UserSubscribe subscribe=userSubscribeMapper.selectById(subId);
        if (subscribe == null) {
            return false;
        }
        Integer originalStatus = subscribe.getStatus();
        Integer originalAutoRenew = subscribe.getAutoRenew();
        // 2. 构建更新条件
        LambdaUpdateWrapper<UserSubscribe> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(UserSubscribe::getId, subId);
        // 3. 只更新非null的字段
        if (status != null) {
            updateWrapper.set(UserSubscribe::getStatus, status);
        }
        if (autoRenew != null) {
            updateWrapper.set(UserSubscribe::getAutoRenew, autoRenew);
        }
        // 4. 执行更新
        int rows = userSubscribeMapper.update(null, updateWrapper);
        UserSubscribe updateSubscribe=userSubscribeMapper.selectById(subId);
        if (updateSubscribe == null) {
            return false; // 更新后记录消失（极端情况）
        }

        // 6. 对比更新前后的字段，判断是否真的发生了变更
        boolean statusChanged = status != null && !Objects.equals(originalStatus, updateSubscribe.getStatus());
        boolean autoRenewChanged = autoRenew != null && !Objects.equals(originalAutoRenew, updateSubscribe.getAutoRenew());
        log.info("更新前的数据：{}",originalStatus);
        log.info("更新后的数据：{}",updateSubscribe.getStatus());
        return statusChanged || autoRenewChanged;
    }

    @Override
    public PageResult<SubscribeDetailVO> getSubscribeList(
            Long userId, Integer status, Integer autoRenew, Integer page, Integer pageSize) {
        // 1. 构建分页对象
        Page<UserSubscribe> queryPage = new Page<>(page, pageSize);
        // 2. 构建查询条件
        LambdaQueryWrapper<UserSubscribe> queryWrapper = new LambdaQueryWrapper<>();
        // 条件筛选：用户ID、订单状态、自动订阅情况
        if (userId != null) {
            queryWrapper.eq(UserSubscribe::getUserId, userId);
        }
        if (status != null) {
            queryWrapper.eq(UserSubscribe::getStatus, status);
        }
        if (autoRenew != null) {
            queryWrapper.eq(UserSubscribe::getAutoRenew, autoRenew);
        }
        // 排序：默认按创建时间降序（最新的在前）
        queryWrapper.orderByDesc(UserSubscribe::getStartDate)
                .orderByDesc(UserSubscribe::getId);
        // 3. 执行分页查询
        Page<UserSubscribe> mpPage = new Page<>(page, pageSize);
        Page<UserSubscribe> resultMpPage = userSubscribeMapper.selectPage(mpPage, queryWrapper);
        // 4. 转换为VO对象
        List<SubscribeDetailVO> records = new ArrayList<>();
        for (UserSubscribe subscribe : resultMpPage.getRecords()){
            SubscribeDetailVO vo = new SubscribeDetailVO();
            BeanUtils.copyProperties(subscribe, vo);
            vo.setUserId(subscribe.getUserId());
            // 关联查询套餐名称
            if (subscribe.getPlanId() != null) {
                Plan plan = planMapper.selectById(subscribe.getPlanId());
                vo.setPlanName(plan != null ? plan.getPlanName() : "未知套餐");
                vo.setPrice(plan != null ? plan.getDiscountPrice() : BigDecimal.valueOf(0));
            } else {
                vo.setPlanName("未关联套餐");
            }
            records.add(vo);
        }

        // 5. 封装分页结果
        PageResult<SubscribeDetailVO> hutoolPageResult = new PageResult<>(
                page,
                pageSize,
                Math.toIntExact(resultMpPage.getTotal()) // MyBatis-Plus的total是long，转换为int（需确保总条数不超过int最大值）
        );
        // 将VO列表添加到PageResult（因继承ArrayList，直接addAll）
        hutoolPageResult.addAll(records);
        return hutoolPageResult;
    }

    @Override
    public Long getSubIdByUserAndSubscription(Integer userId, Integer planId) {
        // 1. 业务参数校验（补充框架未覆盖的校验，如ID合法性）
        if (userId == null || userId <= 0) {
            throw new RuntimeException("用户ID不合法");
        }
        if (planId == null || planId <= 0) {
            throw new RuntimeException("套餐ID不合法");
        }
        Long subId = userSubscribeMapper.selectSubIdByUserIdAndPlanId(userId, planId);
        // 处理无记录的情况
        if (subId == null) {
            throw new RuntimeException(
                    String.format("未找到用户[ID:%d]的订阅记录（订阅计划ID:%d）", userId, planId)
            );
        }
        return subId;
    }

    @Override
    public List<SubscribeDetailVO> selectExpiringSubscribesByParams(Map<String, Object> params) {
        return userSubscribeMapper.selectExpiringSubscribesByParams(params);
    }


}